package cn.csc.module.pay.job.jzborder;

import cn.csc.framework.jzb.vo.JzbResponse;
import cn.csc.framework.tenant.core.job.TenantJob;
import cn.csc.module.pay.controller.admin.jzborder.vo.JzbOrderPageReqVO;
import cn.csc.module.pay.controller.app.jzbtask.vo.AppPayJzbTaskPageReqVO;
import cn.csc.module.pay.dal.dataobject.jzborder.JzbOrderDO;
import cn.csc.module.pay.dal.dataobject.jzbsuborder.PayJzbSubOrderDO;
import cn.csc.module.pay.dal.dataobject.jzbtask.PayJzbTaskDO;
import cn.csc.module.pay.dal.mysql.jzborder.JzbOrderMapper;
import cn.csc.module.pay.dal.mysql.jzbsuborder.PayJzbSubOrderMapper;
import cn.csc.module.pay.dal.mysql.jzbtask.PayJzbTaskMapper;
import cn.csc.module.pay.service.drawcash.PayDrawCashService;
import cn.csc.module.pay.service.jzborder.JzbOrderService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.util.List;

/**
 * @Author：云隐
 * @Date：2023/5/5 18:49
 */
@Component
@TenantJob // 多租户
@Slf4j
public class JzbOrderJob {

    @Resource
    JzbOrderService jzbOrderService;
    @Resource
    PayDrawCashService payDrawCashService;

    @Resource
    private PayJzbTaskMapper payJzbTaskMapper;
    @Resource
    private JzbOrderMapper jzbOrderMapper;

    @Resource
    private PayJzbSubOrderMapper payJzbSubOrderMapper;

    /**
     * 冻结失败
     * 处理jzbFreezeStatus=2的见证宝订单消息，重新发送mq消息
     * @return
     * @throws Exception
     */
    @XxlJob("jzbOrderFreezeJob")
    public ReturnT<String> jzbOrderFreezeJob() throws Exception {
        JzbOrderPageReqVO reqVO = new JzbOrderPageReqVO();
        reqVO.setPageNo(1);
        reqVO.setPageSize(50);
        reqVO.setJzbFreezeStatus(2);
        Integer count = jzbOrderService.payFreezeJob(reqVO);
        log.info("[jzbOrderFreezeJob] {}", String.format("执行冻结失败的冻结 %s 条", count));
        return new ReturnT<>(String.format("执行冻结失败的冻结 %s 个", count));
    }

    /**
     * 提现失败后若需要再进行补充,可以在进行跑动
     * status=2:提现失败
     * @return
     * @throws Exception
     */
    @XxlJob("payDrawCashFailJob")
    public ReturnT<String> payDrawCashFailJob() throws Exception {
        String str = XxlJobHelper.getJobParam();
        Integer count = payDrawCashService.taskDrawCash(2, str);
        return new ReturnT<>(String.format("执行提现失败的任务 %s 个", count));
    }

    /**
     * 手动添加分账任务（jzb_freeze_status=9），任务执行时间为当前
     * 处理见证宝订单中的jzb_freeze_status=9,即订单还未清算的订单
     * @return
     * @throws Exception
     */
    @XxlJob("payDivideJob")
    public ReturnT<String> payDivideJob() throws Exception {
        JzbOrderPageReqVO reqVO = new JzbOrderPageReqVO();
        reqVO.setPageNo(1);
        reqVO.setPageSize(50);
        reqVO.setJzbFreezeStatus(9);
        Long count = jzbOrderService.divideJob(reqVO);
        log.info("[payDivideJob] {}", String.format("添加分账任务 %s 个", count));
        return new ReturnT<>(String.format("添加分账任务 %s 个", count));
    }

    /**
     * 定时执行分账任务
     * 9,10,11,12,13,14,15,16,17,18,19,20 * * ? 每5分钟执行一次
     * @return
     * @throws Exception
     */
    @XxlJob("execDivideTaskJob")
    public ReturnT<String> execDivideTaskJob() throws Exception {
        AppPayJzbTaskPageReqVO pageReqVO = new AppPayJzbTaskPageReqVO();
        pageReqVO.setPageNo(1);
        pageReqVO.setPageSize(50);
        pageReqVO.setBusiType("1");  // 1:分账 2:提现
        pageReqVO.setTaskStatus(0);  // 0:待执行 1:执行成功
        pageReqVO.setTaskTime(LocalDate.now()); // 任务执行时间

        Integer count = jzbOrderService.execDivideTask(pageReqVO);
        log.info("[execDivideTaskJob] {}", String.format("执行分账任务 %s 个", count));
        return new ReturnT<>(String.format("执行分账任务 %s 个", count));
    }

    /**
     * 处理异常分账任务
     * @return
     * @throws Exception
     */
    @XxlJob("dealAbnormalDivide")
    public ReturnT<String> dealAbnormalDivide() throws Exception{
        List<PayJzbSubOrderDO> list = payJzbSubOrderMapper.selectListByOrderStatus(11);
        log.info("[dealAbnormalDivide] 见证宝子订单信息: {}", list.get(0));
        if (CollectionUtils.isEmpty(list)){
            return new ReturnT<>(500, "无任何任务待执行！");
        }
        JzbResponse response = jzbOrderService.dealAbnormalDivide(list.get(0));
        log.info("[dealAbnormalDivide] 分账返回: {}", response);

        return new ReturnT<>(String.format("执行分账任务 %s 个", 1));
    }


    @XxlJob("specialDivideTaskJob")
    public ReturnT<String> specialDivideTaskJob() throws Exception {
        String params = XxlJobHelper.getJobParam();
        log.info("[specialDivideTaskJob] 见证宝订单号、特殊分账账号和分账金额: {}", params);
        String[] split = params.split(";");
        if (split.length != 3){
            log.info("[specialDivideTaskJob] 输入的任务参数: {}", params);
            XxlJobHelper.handleFail("fail");
            return new ReturnT<>(500, "输入的任务参数有误");
        }

        JzbOrderDO jzbOrderDO = jzbOrderMapper.selectById(split[0]);
        jzbOrderService.specialDivideTask(jzbOrderDO, split[1], split[2]);

        return new ReturnT<>("success");
    }


    /**
     * 添加分账任务，用于测试
     * job参数格式：busiType;orderId;jzbOrderId
     */
    @XxlJob("addDivideTaskJob")
    public ReturnT<String> addDivideTaskJob() throws Exception {
        String params = XxlJobHelper.getJobParam();
        String[] split = params.split(";");
        if (split.length <= 0){
            log.info("[addDivideTaskJob] 输入的任务参数: {}", params);
            XxlJobHelper.handleFail("fail");
            return new ReturnT<>(500, "输入的任务参数为空");
        }
        PayJzbTaskDO jzbTaskDO = new PayJzbTaskDO();
        // 1:分账 2:提现
        jzbTaskDO.setBusiType(split[0]);
        jzbTaskDO.setOrderId(new BigInteger(split[1]));
        jzbTaskDO.setJzbOrderId(new BigInteger(split[2]));
        jzbTaskDO.setTaskTime(LocalDate.now());
        // 0:待执行 1:执行成功
        jzbTaskDO.setTaskStatus(0);

        payJzbTaskMapper.insert(jzbTaskDO);
        XxlJobHelper.handleSuccess("success");
        return new ReturnT<>("success");
    }

    /**
     * 修复冻结充值时冻结金额为订单金额造成的异常问题
     * 支持修复指定订单号的数据，若为空则修复所有的订单数据
     * job参数格式：orderId
     */
    @XxlJob("repairSubAccountJob")
    public ReturnT<String> repairSubAccountJob(){
        String orderId = XxlJobHelper.getJobParam();
        log.info("[repairSubAccountJob] 支付订单号: {}", orderId);

        JzbOrderPageReqVO reqVO = new JzbOrderPageReqVO();
        reqVO.setPageNo(1);
        reqVO.setPageSize(50);
        reqVO.setJzbFreezeStatus(5);
        if (StringUtils.hasLength(orderId)){
            reqVO.setPayOrderId(new BigInteger(orderId));
        }

        Integer count = jzbOrderService.repairSubAccount(reqVO);
        log.info("[repairSubAccountJob] {}", String.format("修复异常分账数据 %s 条", count));
        return new ReturnT<>(String.format("修复异常分账数据 %s 条", count));
    }

    /**
     * 修复冻结充值时冻结金额为订单金额造成的异常问题
     * 支持修复指定订单号的数据，若为空则修复所有的订单数据
     * job参数格式：orderId;resumeAmt
     */
    @XxlJob("resumeDivideJob")
    public ReturnT<String> resumeDivideJob(){
        String param = XxlJobHelper.getJobParam();
        log.info("[resumeDivideJob] 支付订单号和分账金额: {}", param);
        String[] split = param.split(";");
        if (split.length != 2){
            XxlJobHelper.handleFail("fail");
            return new ReturnT<>(500, "job参数格式：orderId;resumeAmt");
        }

        JzbOrderDO jzbOrderDO = jzbOrderMapper.selectByPayOrderId(new BigInteger(split[0]));
        JzbResponse response = jzbOrderService.resumeDivide(jzbOrderDO, new BigDecimal(split[1]));
        return new ReturnT<>(response.isSuccess()?"再分账成功" : "再分账失败");
    }



}
